home *** CD-ROM | disk | FTP | other *** search
- #include <ctype.h>
-
- #include "config.h"
- #include "global.h"
- #include "mbuf.h"
- #include "domain.h"
- #include "netuser.h"
- #include "socket.h"
- #include "files.h"
-
- static struct rr *Rrlist[NRLIST];
-
- #ifdef ENH
- struct dlist *Lorigin = NULLDLIST;
- struct rr *Rrlistl[NRLIST];
- char *Dorigin = NULLCHAR;
- #else
- static struct dlist *Lorigin = NULLDLIST;
- static struct rr *Rrlistl[NRLIST];
- static char *Dorigin = NULLCHAR;
- #endif
-
- /*
- static int near
- strxlen(char *s)
- {
- int i = 0;
-
- while(*s++ != '\0')
- i++;
- return i;
- }
- */
-
- int
- sendquery(address,buf,len,bp,timeout)
- int32 address;
- char *buf;
- int len;
- struct mbuf **bp;
- int32 timeout;
- {
- int s, resp = -1;
- struct sockaddr_in server;
-
- if((s = socket(AF_INET,SOCK_DGRAM,0)) != -1) {
- *bp = qdata(buf,(int16)len);
- xfree(buf);
- server.sin_family = AF_INET;
- server.sin_port = IPPORT_DOMAIN;
- server.sin_addr.s_addr = address;
- send_mbuf(s,*bp,0,(char *)&server,sizeof(server));
- if(timeout) { /* Wait for something to happen */
- alarm(timeout);
- resp = recv_mbuf(s,bp,0,NULLCHAR,0);
- alarm(0L);
- }
- close_s(s);
- }
- return resp;
- }
-
- static char * near
- dn_compress(char *cp,char *name)
- {
- char *cp1;
- int len, dlen = strlen(name);
-
- for(;;){
- /* Look for next dot */
- cp1 = strchr(name,'.');
- len = (cp1 != NULLCHAR) ? (int)(cp1 - name) : dlen;
- *cp++ = len; /* Write length of component */
- if(len == 0)
- return cp;
- /* Copy component up to (but not including) dot */
- strncpy(cp,name,len);
- cp += len;
- if(cp1 == NULLCHAR){
- *cp++ = 0; /* Last one; write null and finish */
- return cp;
- }
- name += len+1;
- dlen -= len+1;
- }
- }
-
- /* Convert a compressed domain name to the human-readable form */
- static int near
- dn_expand(msg,eom,compressed,full,fullen)
- char *msg; /* Complete domain message */
- char *eom;
- char *compressed; /* Pointer to compressed name */
- char *full; /* Pointer to result buffer */
- int fullen; /* Length of same */
- {
- unsigned int slen; /* Length of current segment */
- int clen = 0; /* Total length of compressed name */
- int indirect = 0; /* Set if indirection encountered */
- int nseg = 0; /* Total number of segments in name */
- char *cp = compressed;
-
- for(;;){
- slen = uchar(*cp++); /* Length of this segment */
- if(!indirect)
- clen++;
- if((slen & 0xc0) == 0xc0){
- if(!indirect)
- clen++;
- indirect = 1;
- /* Follow indirection */
- cp = &msg[((slen & 0x3f)<<8) + uchar(*cp)];
- slen = uchar(*cp++);
- }
- if(slen == 0) /* zero length == all done */
- break;
- fullen -= slen + 1;
- if(fullen < 0)
- return -1;
- if(!indirect)
- clen += slen;
- while(slen-- != 0)
- *full++ = *cp++;
- *full++ = '.';
- nseg++;
- }
- if(nseg == 0){
- /* Root name; represent as single dot */
- *full++ = '.';
- fullen--;
- }
- *full++ = '\0';
- fullen--;
- return clen; /* Length of compressed message */
- }
-
- static char * near
- getq(qp,msg,cp)
- struct quest *qp;
- char *msg;
- char *cp;
- {
- int len;
- char name[512];
-
- if((len = dn_expand(msg,NULLCHAR,cp,name,sizeof(name))) == -1)
- return NULLCHAR;
- cp += len;
- qp->qname = strxdup(name);
- qp->qtype = get16(cp);
- cp += 2;
- qp->qclass = get16(cp);
- cp += 2;
- return cp;
- }
-
- /* Read a resource record from a domain message into a host structure */
- static char * near
- ntohrr(rrp,msg,cp)
- struct rr *rrp; /* Pointer to allocated resource record structure */
- char *msg; /* Pointer to beginning of domain message */
- char *cp; /* Pointer to start of encoded RR record */
- {
- int len;
- char name[512];
-
- if((len = dn_expand(msg,NULLCHAR,cp,name,sizeof(name))) == -1)
- return NULLCHAR;
- cp += len;
- rrp->name = strxdup(name);
- rrp->type = get16(cp);
- cp += 2;
- rrp->class = get16(cp);
- cp+= 2;
- rrp->ttl = get32(cp);
- cp += 4;
- rrp->rdlength = get16(cp);
- cp += 2;
- switch(rrp->type){
- case TYPE_CNAME:
- case TYPE_MB:
- case TYPE_MG:
- case TYPE_MR:
- case TYPE_NS:
- case TYPE_PTR:
- /* These types all consist of a single domain name;
- * convert it to ascii format
- */
- if((len = dn_expand(msg,NULLCHAR,cp,name,sizeof(name))) == -1)
- return NULLCHAR;
- rrp->rdata.name = strxdup(name);
- cp += len;
- break;
- case TYPE_A:
- /* Just read the address directly into the structure */
- rrp->rdata.addr = get32(cp);
- cp += 4;
- break;
- case TYPE_HINFO:
- rrp->rdata.hinfo.cpu = (char *)mxallocw(*cp+1);
- strncpy(rrp->rdata.hinfo.cpu,cp+1,*cp);
- cp += *cp + 1;
- rrp->rdata.hinfo.os = (char *)mxallocw(*cp+1);
- strncpy(rrp->rdata.hinfo.os,cp+1,*cp);
- cp += *cp + 1;
- break;
- case TYPE_MX:
- rrp->rdata.mx.pref = get16(cp);
- cp += 2;
- /* Get domain name of exchanger */
- if((len = dn_expand(msg,NULLCHAR,cp,name,sizeof(name))) == -1) {
- xfree(rrp->name);
- return NULLCHAR;
- }
- rrp->rdata.mx.exch = strxdup(name);
- cp += len;
- break;
- case TYPE_SOA:
- /* Get domain name of name server */
- if((len = dn_expand(msg,NULLCHAR,cp,name,sizeof(name))) == -1) {
- xfree(rrp->name);
- return NULLCHAR;
- }
- rrp->rdata.soa = (struct soa *)mxallocw(sizeof(struct soa));
- rrp->rdata.soa->mname = strxdup(name);
- cp += len;
-
- /* Get domain name of responsible person */
- if((len = dn_expand(msg,NULLCHAR,cp,name,sizeof(name))) == -1) {
- xfree(rrp->rdata.soa->mname);
- xfree(rrp->rdata.soa);
- xfree(rrp->name);
- return NULLCHAR;
- }
- rrp->rdata.soa->rname = strxdup(name);
- cp += len;
-
- rrp->rdata.soa->serial = get32(cp);
- cp += 4;
- rrp->rdata.soa->refresh = get32(cp);
- cp += 4;
- rrp->rdata.soa->retry = get32(cp);
- cp += 4;
- rrp->rdata.soa->expire = get32(cp);
- cp += 4;
- rrp->rdata.soa->minimum = get32(cp);
- cp += 4;
- break;
- case TYPE_TXT:
- /* Just stash */
- rrp->rdata.data = mxallocw(rrp->rdlength);
- memcpy(rrp->rdata.data,cp,rrp->rdlength);
- cp += rrp->rdlength;
- break;
- case TYPE_MD: /* Not supported */
- case TYPE_MF: /* Not supported */
- case TYPE_NULL: /* Not supported */
- case TYPE_WKS: /* Not supported */
- case TYPE_MINFO: /* Not supported */
- if((len = dn_expand(msg,NULLCHAR,cp,name,sizeof(name))) == -1) {
- xfree(rrp->name);
- return NULLCHAR;
- }
- rrp->rdata.name = strxdup(name);
- cp += len;
- break;
- default:
- /* Ignore */
- cp += rrp->rdlength;
- break;
- }
- return cp;
- }
-
- static char * near
- htonrr(rr,buffer)
- struct rr *rr;
- char *buffer;
- {
- struct rr *rrp;
- char *p;
- int i, len;
- char *cp = buffer;
-
- for(rrp = rr; rrp != NULLRR; rrp = rrp->next) {
- i = strlen(rrp->name);
- if(rrp->name[i-1] != '.' && rrp->origin != NULLCHAR) {
- p = mxallocw(i + strlen(rrp->origin) + 2);
- sprintf(p,"%s.%s",rrp->name,rrp->origin);
- cp = dn_compress(cp,p);
- xfree(p);
- }
- else
- cp = dn_compress(cp,rrp->name);
- cp = put16(cp,rrp->type);
- cp = put16(cp,rrp->class);
- cp = put32(cp,3600L); /* time to live */
- cp = put16(cp,rrp->rdlength);
- switch(rrp->type) {
- case TYPE_A:
- cp = put32(cp,rrp->rdata.addr);
- break;
- case TYPE_SOA:
- cp = dn_compress(cp,rrp->rdata.soa->mname);
- cp = dn_compress(cp,rrp->rdata.soa->rname);
- cp = put32(cp,rrp->rdata.soa->serial);
- cp = put32(cp,rrp->rdata.soa->refresh);
- cp = put32(cp,rrp->rdata.soa->retry);
- cp = put32(cp,rrp->rdata.soa->expire);
- cp = put32(cp,rrp->rdata.soa->minimum);
- break;
- case TYPE_HINFO:
- *cp++ = len = strlen(rrp->rdata.hinfo.cpu);
- strncpy(cp,rrp->rdata.hinfo.cpu,len);
- cp += len;
- *cp++ = len = strlen(rrp->rdata.hinfo.os);
- strncpy(cp,rrp->rdata.hinfo.os,len);
- cp += len;
- break;
- case TYPE_MX:
- cp = put16(cp,rrp->rdata.mx.pref);
- cp = dn_compress(cp,rrp->rdata.mx.exch);
- break;
- case TYPE_CNAME:
- case TYPE_MB:
- case TYPE_MG:
- case TYPE_MR:
- case TYPE_NS:
- case TYPE_PTR:
- cp = dn_compress(cp,rrp->rdata.data);
- break;
- case TYPE_MINFO: /* Unsupported type */
- cp = dn_compress(cp,rrp->rdata.minfo.rmailbx);
- cp = dn_compress(cp,rrp->rdata.minfo.emailbx);
- case TYPE_MD: /* Unsupported type */
- case TYPE_MF: /* Unsupported type */
- case TYPE_NULL: /* Unsupported type */
- case TYPE_WKS: /* Unsupported type */
- cp = dn_compress(cp,rrp->rdata.data);
- break;
- case TYPE_TXT:
- default:
- cp = put16(cp,rrp->rdlength);
- for(i=0 ; i < rrp->rdlength ; i++)
- *cp++ = rrp->rdata.data[i];
- break;
- }
- }
- return cp;
- }
-
- /* analyse suffixes for names to be added to the memory list */
- /* if Lorigin is empty, PA0GRI's domain stuf is not active. */
- static void near
- analsuf(rrp)
- struct rr *rrp;
- {
- char *n1, *n2;
- int i;
- struct dlist *llist, *lorigin;
-
- if(rrp->origin != NULLCHAR)
- return; /* no job for me. */
- if((llist = Lorigin) != NULLDLIST) { /* Am i working for PA0GRI? */
- i = strlen(rrp->name);
- if(rrp->name[i-1] == '.') {
- n1 = &rrp->name[i-1];
- n2 = strchr(rrp->name,'.');
- if(n1 == n2){
- return; /* only 1 dot */
- }
- n2++; /* point byond dot */
- while(llist != NULLDLIST) {
- lorigin = llist;
- if(strcmp(llist->name,n2) == 0)
- break;
- llist = llist->next;
- }
- if(llist == NULLDLIST) {
- llist = (struct dlist *)mxallocw(sizeof(struct dlist));
- llist->name = strxdup(n2);
- lorigin->next = llist;
- }
- rrp->origin = llist->name;
- n2--;
- *n2 = '\0'; /* dot to EOS */
- n1 = strxdup(rrp->name);
- xfree(rrp->name);
- rrp->name = n1;
- }
- }
- }
-
- /* test a rr against a given name and type. The name can be:
- 1 a fully qualified name (EG: pa0gri.ampr.org.)
- or (if not fully qualified)
- 2 a name without a dot and no origin and suffix
- 3 a name without a dot and an origin and no suffix
- 4 a name without a dot and an origin and a suffix
- *
- * return 0 if not comparable, case value if it is good
- */
- static int near
- dfind_cmp(rrp,name,nlen,dlen)
- struct rr *rrp;
- char *name;
- int nlen;
- int dlen;
- {
- int olen = 0, rlen = strlen(rrp->name);
-
- if(rrp->origin != NULLCHAR) {
- olen = strlen(rrp->origin);
- if(rrp->origin[olen - 1] == '.')
- --olen;
- }
-
- /* 1st test: is the name equal to the fully qualified rrp name? (minus traling .) */
- if(rrp->name[rlen - 1] == '.') {
- --rlen;
- if(rlen == nlen && strnicmp(name,rrp->name,rlen) == 0)
- return 1;
- }
-
- /* second test: is the name equal to the rrp name */
- if(Dsuffix == NULLCHAR && rrp->origin == NULLCHAR) {
- if(nlen == rlen && strnicmp(name,rrp->name,rlen) == 0)
- return 2;
- if(nlen + 9 == rlen /* special case for .ampr.org. */
- && strnicmp(name,rrp->name,nlen) == 0
- && strnicmp(&rrp->name[nlen+1],"ampr.org",8) == 0
- && rrp->name[nlen] == '.')
- return 3;
- } else if(Dsuffix == NULLCHAR && rrp->origin != NULLCHAR) {
- if(nlen == rlen && strnicmp(name,rrp->name,rlen) == 0)
- /* third test: name equal to rrp name (excluding origin) */
- return 4;
- else if((rlen + olen + 1) == nlen
- && strnicmp(name,rrp->name,rlen) == 0
- && name[rlen] == '.'
- && strnicmp(&name[rlen + 1],rrp->origin,olen) == 0)
- /* fourth test: name equal rrp name + origin */
- return 5;
- } else if(Dsuffix != NULLCHAR && rrp->origin != NULLCHAR) {
- if(rlen == nlen && dlen == olen
- && strnicmp(name,rrp->name,rlen) == 0
- && strnicmp(Dsuffix,rrp->origin,dlen) == 0)
- /* fifth test: name equal to rrp name and origin equal to domain suffix */
- return 6;
- else if((rlen + olen + 1) == nlen
- && strnicmp(name,rrp->name,rlen) == 0
- && name[rlen] == '.'
- && strnicmp(&name[rlen + 1],rrp->origin,olen) == 0)
- /* sixth test: name equal to rrp name + origin) */
- return 7;
- } else if(Dsuffix != NULLCHAR && rrp->origin == NULLCHAR) {
- if(rlen == nlen && strnicmp(name,rrp->name,rlen) == 0)
- /* seventh test: name equal to rrp name and no origin (ignore domain suffix) */
- return 8;
- else
- if((nlen + dlen + 1) == rlen
- && strnicmp(name,rrp->name,nlen) == 0
- && rrp->name[nlen] == '.'
- && strnicmp(&rrp->name[nlen + 1],Dsuffix,dlen) == 0)
- /* eight test: name plus suffix equal to rrp name ) */
- return 9;
- }
- return 0;
- }
-
- /* Search local domain file for resource record of specified name and type.
- * If records were found, the domain file pointer is left just after the last
- * one. If not, the file is rewound.
- */
- static struct rr * near
- dfindf(dbase,name,type,memory)
- FILE *dbase;
- char *name;
- int type;
- struct rr_memory *memory;
- {
- struct rr *rrp;
- int nlen, dlen;
-
- if(DBloaded)
- return NULLRR;
-
- nlen = strlen(name);
- if(name[nlen - 1] == '.') /* forget trailing . for tests. */
- --nlen;
-
- dlen = (Dsuffix != NULLCHAR) ? (strlen(Dsuffix) - 1) : 0;
- /* Search file */
- while((rrp = get_rr(dbase,memory)) != NULLRR){
- if(rrp->class == CLASS_IN)
- if(type == rrp->type || type == TYPE_ANY)
- if(dfind_cmp(rrp,name,nlen,dlen) != 0)
- break;
- free_rr(rrp);
- pwait(NULL); /* Give up CPU for a while, this takes time */
- }
- if(rrp == NULLRR)
- rewind(dbase);
- return rrp;
- }
- #ifdef forgetme
- /* If the first character is a '*' it is replaced by the
- first part of the sought domain. */
- /* forget about this till other areas know what to do with multiple rr's.
- if(*rrp->name == '*'){
- if(rrp->name[rlen-1] == '.')
- p = mxallocw(rlen);
- else
- p = mxallocw(rlen + olen);
- strcpy(p,rrp->name+2);
- if(rrp->name[rlen-1] != '.' && rrp->origin != NULLCHAR)
- strcat(p,rrp->origin);
- rrp->origin = p;
- olen = strlen(rrp->origin);
- if(rrp->origin[olen-1] == '.')
- --olen;
- xfree(rrp->name);
- rrp->name = (char *)mxallocw(nlen + 1);
- if(nlen > olen
- && strnicmp(name+nlen-olen,rrp->origin, olen) == 0)
- strncpy(rrp->name,name,nlen-olen-1);
- else {
- free_rr(rrp);
- continue;
- }
- rlen = strlen(rrp->name);
- }
- end of skip code */
- #endif
-
- struct rr *
- dfind(dbase,name,type,memory)
- FILE *dbase;
- char *name;
- int type;
- struct rr_memory *memory;
- {
- struct rr *rrp, *rrl;
- int nlen, dlen, i, rtype;
- struct rr *rrsave = NULLRR;
-
- if(type >= NDTYPES)
- if(type == TYPE_ANY) {
- for(i = 0 ; (rtype = Dstypes[i]) != 0; ) {
- rrp = dfind(dbase,name,rtype,memory);
- if(rrp != NULLRR) {
- if(rrsave == NULLRR){
- rrsave = rrp;
- rrl = rrp;
- } else {
- rrl->next = rrp;
- rrl = rrl->next;
- }
- } else {
- i++;
- memory->rrp = NULLRR;
- }
- }
- if(rrsave != NULLRR)
- return rrsave;
- } else {
- goto filetest; /* to big a type for memory */
- }
- if((rrp = Rrlist[type]) != NULLRR) {
- if(memory->rrp != NULLRR){
- rrp = memory->rrp; /* go off where we left before ! */
- rrp = rrp->next; /* but take the next */
- }
- nlen = strlen(name);
- if(name[nlen - 1] == '.') /* forget trailing . for tests. */
- --nlen;
- dlen = (Dsuffix != NULLCHAR) ? (strlen(Dsuffix) - 1) : 0;
-
- /* Search core data beast */
- while(rrp != NULLRR){
- if(rrp->class == CLASS_IN)
- if(dfind_cmp(rrp,name,nlen,dlen) != 0)
- break;
- rrp = rrp->next;
- }
- if(rrp != NULLRR){
- rrl = copy_rr(rrp);
- memory->rrp = rrp;
- return rrl;
- }
- memory->rrp = NULLRR; /* end of list encountered */
- } /* not found in memory, resort to file */
- filetest:
- if(dbase != NULLFILE)
- rrp = dfindf(dbase,name,type,memory);
- return rrp;
- }
-
- /* Add a record to the database only if it doesn't already exist */
- /* Return 1 if record is not added to memory list. This means the rr
- can be freed. If 0 is returned the rr is added to the memory list */
- #ifndef ENH
- static
- #endif
- int
- add_rr(fp,rrp1)
- FILE *fp;
- struct rr *rrp1;
- {
- int type, nlen;
- char *name;
- struct rr *rrp, *rr;
- struct rr_memory *memory;
-
- analsuf(rrp1);
- type = rrp1->type;
- name = rrp1->name;
- nlen = strlen(name);
- memory = (struct rr_memory *)mxallocw(sizeof(struct rr_memory));
- memory->rrp = NULLRR;
- if(fp == NULLFILE) {
- name = strxdup(rrp1->name);
- while((rrp = dfind(fp,name,type,memory)) != NULLRR){
- if(cmp_rr(rrp,rrp1) == 0){
- free_rr(rrp);
- xfree(memory->dorigin);
- xfree((char *)memory);
- xfree(name);
- return 1;
- }
- free_rr(rrp);
- }
- /* Not found in list, go add it */
- xfree(memory->dorigin);
- xfree((char *)memory);
- xfree(name);
- /* see if we have this kind of records. */
- if((rr = Rrlist[type]) != NULLRR) {
- rr = Rrlistl[type];
- rr->next = rrp1;
- } else /* No, initialize first */
- Rrlist[rrp1->type] = rrp1;
- /* now set last */
- Rrlistl[type] = rrp1;
- return 0;
- } else {
- if(name[nlen - 1] != '.') {
- if(rrp1->origin != NULLCHAR){
- name = (char *)mxallocw(nlen+strlen(rrp1->origin)+2);
- sprintf(name,"%s.%s",rrp1->name,rrp1->origin);
- }
- } else
- name = strxdup(rrp1->name);
- rewind(fp);
- while((rrp = dfind(fp,name,type,memory)) != NULLRR){
- if(cmp_rr(rrp,rrp1) == 0){
- free_rr(rrp);
- xfree(memory->dorigin);
- xfree((char *)memory);
- xfree(name);
- return 1;
- }
- free_rr(rrp);
- }
- xfree(memory->dorigin);
- xfree((char *)memory);
- xfree(name);
- fseek(fp,0L,2);
- put_rr(fp,rrp1,1);
- return 1;
- }
- }
-
- /* Compare two resource records, returning 0 if equal, nonzero otherwise */
- static int
- cmp_rr(rr1,rr2)
- struct rr *rr1,*rr2;
- {
- int i;
-
- if(rr1 == NULLRR || rr2 == NULLRR)
- return -1;
- if((i = strlen(rr1->name)) != strlen(rr2->name))
- return 1;
- if((i = strnicmp(rr1->name,rr2->name,i)) != 0)
- return i;
- if(rr1->type != rr2->type)
- return 2;
- if(rr1->class != rr2->class)
- return 3;
- if(rr1->rdlength == 0 && rr2->rdlength == 0)
- return 0;
- if(rr1->rdlength == 0 || rr2->rdlength == 0)
- return 4;
- /* Note: rdlengths are not compared because they vary depending
- * on the representation (ASCII or encoded) this record was
- * generated from.
- */
- switch(rr1->type){
- case TYPE_A:
- i = rr1->rdata.addr != rr2->rdata.addr;
- break;
- case TYPE_SOA:
- i = rr1->rdata.soa->serial != rr2->rdata.soa->serial;
- break;
- case TYPE_HINFO:
- i = strcmp(rr1->rdata.hinfo.cpu,rr2->rdata.hinfo.cpu) ||
- strcmp(rr1->rdata.hinfo.os,rr2->rdata.hinfo.os);
- break;
- case TYPE_MX:
- i = strcmp(rr1->rdata.mx.exch,rr2->rdata.mx.exch);
- break;
- case TYPE_MB:
- case TYPE_MG:
- case TYPE_MR:
- case TYPE_PTR:
- case TYPE_TXT:
- case TYPE_NS:
- i = strcmp(rr1->rdata.data,rr2->rdata.data);
- break;
- case TYPE_CNAME:
- i = strcmp(rr1->rdata.data,rr2->rdata.data);
- break;
- case TYPE_MINFO: /* Unsupported type */
- i = strcmp(rr1->rdata.minfo.rmailbx,rr2->rdata.minfo.rmailbx) ||
- strcmp(rr1->rdata.minfo.emailbx,rr2->rdata.minfo.emailbx);
- break;
- case TYPE_MD: /* Unsupported type */
- case TYPE_MF: /* Unsupported type */
- case TYPE_NULL: /* Unsupported type */
- case TYPE_WKS: /* Unsupported type */
- i = strcmp(rr1->rdata.data,rr2->rdata.data);
- break;
- }
- return i;
- }
-
- struct rr *
- copy_rr(rr)
- struct rr *rr;
- {
- struct rr *rrp = (struct rr *)mxallocw(sizeof(struct rr));
-
- rrp->next = NULLRR;
- rrp->soarec = rr->soarec;
- rrp->name = strxdup(rr->name);
- rrp->type = rr->type;
- rrp->class = rr->class;
- rrp->ttl = rr->ttl;
- rrp->origin = rr->origin;
- rrp->rdlength = rr->rdlength;
- switch(rr->type){
- case TYPE_A:
- rrp->rdata.addr = rr->rdata.addr;
- break;
- case TYPE_CNAME:
- case TYPE_MB:
- case TYPE_MG:
- case TYPE_MR:
- case TYPE_NS:
- case TYPE_PTR:
- case TYPE_TXT:
- rrp->rdata.name = strxdup(rr->rdata.name);
- break;
- case TYPE_HINFO:
- rrp->rdata.hinfo.cpu = strxdup(rr->rdata.hinfo.cpu);
- rrp->rdata.hinfo.os = strxdup(rr->rdata.hinfo.os);
- break;
- case TYPE_MX:
- rrp->rdata.mx.pref = rr->rdata.mx.pref;
- rrp->rdata.mx.exch = strxdup(rr->rdata.mx.exch);
- break;
- case TYPE_SOA:
- rrp->rdata.soa = (struct soa *)mxallocw(sizeof(struct soa));
- rrp->rdata.soa->mname = strxdup(rr->rdata.soa->mname);
- rrp->rdata.soa->rname = strxdup(rr->rdata.soa->rname);
- rrp->rdata.soa->serial = rr->rdata.soa->serial;
- rrp->rdata.soa->refresh = rr->rdata.soa->refresh;
- rrp->rdata.soa->retry = rr->rdata.soa->retry;
- rrp->rdata.soa->expire = rr->rdata.soa->expire;
- rrp->rdata.soa->minimum = rr->rdata.soa->minimum;
- break;
- case TYPE_MINFO: /* Unsupported type */
- rrp->rdata.minfo.rmailbx = strxdup(rr->rdata.minfo.rmailbx);
- rrp->rdata.minfo.emailbx = strxdup(rr->rdata.minfo.emailbx);
- break;
- case TYPE_MD: /* Unsupported type */
- case TYPE_MF: /* Unsupported type */
- case TYPE_NULL: /* Unsupported type */
- case TYPE_WKS: /* Unsupported type */
- rrp->rdata.name = strxdup(rr->rdata.name);
- break;
- }
- return rrp;
- }
-
- #ifdef XXX
- struct rr *
- make_rr(source,dname,dclass,dtype,ttl,rdl,data)
- int source;
- char *dname;
- int16 dclass;
- int16 dtype;
- int32 ttl;
- int16 rdl;
- void *data;
- {
- struct rr *newrr = (struct rr *)mxallocw(sizeof(struct rr));
-
- newrr->next = NULLRR;
- newrr->soarec = NULLRR;
- newrr->name = strxdup(dname);
- newrr->class = dclass;
- newrr->type = dtype;
- newrr->ttl = ttl;
- if((newrr->rdlength = rdl) == 0)
- return newrr;
-
- if(dtype == TYPE_A) {
- int32 *ap = (int32 *)data;
- newrr->rdata.addr = *ap;
- }
- return copy_rr(newrr);
- }
- #endif
-
- /* Free a chain of resource records */
- void
- free_rr(rrp)
- struct rr *rrp;
- {
- struct rr *rr = rrp;
-
- while(rr != NULLRR) {
- rrp = rr;
- xfree(rrp->name);
- if(rrp->rdlength != 0){
- switch(rrp->type){
- case TYPE_CNAME:
- case TYPE_MB:
- case TYPE_MG:
- case TYPE_MR:
- case TYPE_NS:
- case TYPE_PTR:
- xfree(rrp->rdata.name);
- break;
- case TYPE_A:
- break; /* Nothing allocated in rdata section */
- case TYPE_HINFO:
- xfree(rrp->rdata.hinfo.cpu);
- xfree(rrp->rdata.hinfo.os);
- break;
- case TYPE_MX:
- xfree(rrp->rdata.mx.exch);
- break;
- case TYPE_SOA:
- xfree(rrp->rdata.soa->mname);
- xfree(rrp->rdata.soa->rname);
- xfree((char *)rrp->rdata.soa);
- break;
- case TYPE_TXT:
- xfree(rrp->rdata.data);
- break;
- case TYPE_MD: /* Unsupported type */
- case TYPE_MF: /* Unsupported type */
- case TYPE_NULL: /* Unsupported type */
- xfree(rrp->rdata.data);
- break;
- case TYPE_WKS: /* Unsupported type */
- break;
- case TYPE_MINFO: /* Unsupported type */
- xfree(rrp->rdata.minfo.rmailbx);
- xfree(rrp->rdata.minfo.emailbx);
- break;
- }
- }
- rr = rrp->next;
- xfree((char *)rrp);
- }
- }
-
- #ifndef ENH
- static
- #endif
- struct rr *
- get_rr(fp,memory)
- FILE *fp;
- struct rr_memory *memory;
- {
- char line[256], contline[256];
- struct rr *rrp;
- struct dlist *lorigin,*ltemp;
- char *name, *ttl, *class, *type, *data;
- int i;
- int32 value, atol();
- char delim[] = " \t\r\n";
-
- if(fp == NULLFILE)
- return NULLRR;
-
- /* Search file */
- while(fgets(line,sizeof(line),fp),!feof(fp)){
- if(*line == '#' || *line == ';')
- continue;
- if(*line == '$') {
- data = strtok(line,delim);
- if(strnicmp(data,"$origin",7) == 0) {
- data = strtok(NULLCHAR,delim);
- if(Db_initialize) {
- if(data != NULLCHAR) {
- ltemp = Lorigin;
- while(ltemp != NULLDLIST) {
- lorigin = ltemp;
- if(strcmp(ltemp->name,data) == 0)
- break;
- ltemp = ltemp->next;
- }
- if(ltemp == NULLDLIST) {
- ltemp = (struct dlist *)mxallocw(sizeof(struct dlist));
- ltemp->name = strxdup(data);
- lorigin->next = ltemp;
- Dorigin = ltemp->name;
- } else {
- Dorigin = ltemp->name;
- }
- } else {
- Dorigin = NULLCHAR; /* empty origin */
- }
- }
- if(memory->dorigin != NULLCHAR)
- xfree(memory->dorigin);
- memory->dorigin = (data != NULLCHAR) ? strxdup(data) : NULLCHAR;
- }
- continue;
- }
- data = &line[0]; /* check for empty line */
- while(*data)
- if(!isspace(*data++)) {
- break;
- }
- /*
- * now it is nor a # , ; or $ line
- */
- if(*data)
- break; /* there is something on it.. */
- }
-
- if(feof(fp))
- return NULLRR;
-
- rrp = (struct rr *)mxallocw(sizeof(struct rr));
- if(isspace(line[0])) { /* in case of previous name usage*/
- name = "";
- ttl = strtok(line,delim);
- } else {
- name = strtok(line,delim);
- if(!strcmp(name,"@") && (memory->dorigin != NULLCHAR
- || Dsuffix != NULLCHAR)){
- name = (memory->dorigin != NULLCHAR) ? memory->dorigin : Dsuffix;
- }
- ttl = strtok(NULLCHAR,delim);
- }
- if(ttl == NULLCHAR) /* If a line only contains a name */
- goto badline;
-
- if((i = strlen(name)) == 0)
- name = memory->Dname;
- else
- sprintf(memory->Dname,"%.125s",name);
-
- rrp->origin = (Dorigin != NULLCHAR) ? Dorigin : memory->dorigin;
-
- if(name[i-1] == '.') /* if a fully qualified name comes along */
- rrp->origin = NULLCHAR; /* then it does not belong to an origin */
- rrp->name = strxdup(name);
-
- if(!isdigit(ttl[0])){
- /* Optional ttl field is missing; slide field over */
- class = ttl;
- ttl = NULLCHAR;
- rrp->ttl = memory->Dttl;
- } else {
- memory->Dttl = atol(ttl);
- rrp->ttl = memory->Dttl;
- class = strtok(NULLCHAR,delim);
- }
-
- if(class == NULLCHAR) /* If a line only contains a name and ttl */
- goto badline;
-
- if(strcmp(class,"IN") != 0){
- /* Optional class field is missing; slide field over */
- type = class;
- class = NULLCHAR;
- rrp->class = memory->Dclass;
- } else {
- memory->Dclass = CLASS_IN;
- rrp->class = memory->Dclass;
- type = strtok(NULLCHAR,delim);
- }
-
- if(type == NULLCHAR) { /* If a class field is missing */
- badline:
- tprintf("Error in domain file %s:\n-%s-\n",Dfile,line);
- free_rr(rrp);
- return NULLRR;
- }
-
- for(i = 0; i < NRLIST; i++) {
- if(strcmp(type,type2str(i)) == 0){
- rrp->type = i;
- break;
- }
- }
-
- data = strtok(NULLCHAR,delim);
-
- if(data == NULLCHAR)
- return rrp;
-
- switch(rrp->type){
- case TYPE_MD: /* Unsupported yet */
- case TYPE_MF: /* Unsupported yet */
- case TYPE_NULL: /* Unsupported yet */
- rrp->rdlength = strlen(data) + 1;
- rrp->rdata.name = strxdup(data);
- break;
- case TYPE_WKS: /* Unsupported yet */
- /*
- rrp->wks = (struct wks *)mxallocw(sizeof(struct wks));
- */
- rrp->rdlength = strlen(data) + 1;
- rrp->rdata.name = strxdup(data);
- break;
- case TYPE_CNAME:
- case TYPE_MB:
- case TYPE_MG:
- case TYPE_MR:
- case TYPE_NS:
- case TYPE_PTR:
- case TYPE_TXT:
- rrp->rdlength = strlen(data) + 1;
- rrp->rdata.name = strxdup(data);
- break;
- case TYPE_A:
- rrp->rdlength = 4;
- rrp->rdata.addr = aton(data);
- break;
- case TYPE_HINFO:
- rrp->rdlength = strlen(data) + 2;
- rrp->rdata.hinfo.cpu = strxdup(data);
- if((data = strtok(NULLCHAR,delim)) != NULLCHAR){
- rrp->rdlength += strlen(data);
- rrp->rdata.hinfo.os = strxdup(data);
- }
- break;
- case TYPE_MINFO:
- rrp->rdlength = strlen(data) + 2;
- rrp->rdata.minfo.rmailbx = strxdup(data);
- if((data = strtok(NULLCHAR,delim)) != NULLCHAR){
- rrp->rdlength += strlen(data);
- rrp->rdata.minfo.emailbx = strxdup(data);
- }
- break;
- case TYPE_MX:
- rrp->rdata.mx.pref = (int16)atoi(data);
- rrp->rdlength = 2;
-
- /* Get domain name of exchanger */
- if((data = strtok(NULLCHAR,delim)) != NULLCHAR){
- rrp->rdlength += strlen(data) + 1;
- rrp->rdata.mx.exch = strxdup(data);
- }
- break;
- case TYPE_SOA:
- rrp->rdata.soa = (struct soa *)mxallocw(sizeof(struct soa));
- /* Get domain name of master name server */
- rrp->rdlength = strlen(data) + 1;
- rrp->rdata.soa->mname = strxdup(data);
-
- /* Get domain name of irresponsible person */
- if((data = strtok(NULLCHAR,delim)) != NULLCHAR){
- rrp->rdata.soa->rname = strxdup(data);
- rrp->rdlength += strlen(data) + 1;
- }
- data = strtok(NULLCHAR,delim);
- if(*data == '(') { /* multiple line data */
- /* Search file */
- fgets(contline,256,fp);
- if(feof(fp))
- break;
- data = strtok(contline,delim);
- for(i=0; i<5;i++) {
- if(*data == ';' || data == NULLCHAR) {
- fgets(contline,256,fp);
- if(feof(fp)){
- break;
- }
- data = strtok(contline,delim);
- }
- if(*data == ')')
- break;
- if(isdigit(*data)) {
- value = atol(data);
- switch (i) {
- case 0:
- rrp->rdata.soa->serial = value;
- break;
- case 1:
- rrp->rdata.soa->refresh = value;
- break;
- case 2:
- rrp->rdata.soa->retry = value;
- break;
- case 3:
- rrp->rdata.soa->expire = value;
- break;
- case 4:
- rrp->rdata.soa->minimum = value;
- break;
- }
- }
- data = strtok(NULLCHAR,delim);
- }
- } else {
- rrp->rdata.soa->serial = atol(data);
- data = strtok(NULLCHAR,delim);
- rrp->rdata.soa->refresh = atol(data);
- data = strtok(NULLCHAR,delim);
- rrp->rdata.soa->retry = atol(data);
- data = strtok(NULLCHAR,delim);
- rrp->rdata.soa->expire = atol(data);
- data = strtok(NULLCHAR,delim);
- rrp->rdata.soa->minimum = atol(data);
- }
- rrp->rdlength += 20;
- break;
- }
- return rrp;
- }
-
- /* Print a resource record */
- #ifndef ENH
- static
- #endif
- void
- put_rr(fp,rrp,addorg)
- FILE *fp;
- struct rr *rrp;
- int addorg;
- {
- if(fp == NULLFILE || rrp == NULLRR)
- return;
-
- fputs(rrp->name,fp);
-
- if(addorg) {
- if(rrp->name[strlen(rrp->name)-1] != '.' && rrp->origin != NULLCHAR){
- fprintf(fp,".%s",rrp->origin);
- }
- }
- if(rrp->ttl){
- fprintf(fp,"\t%lu",rrp->ttl);
- }
- if(rrp->class == CLASS_IN){
- fputs("\tIN",fp);
- } else {
- if(rrp->ttl == 0)
- fprintf(fp,"\t%lu",rrp->ttl);
- fprintf(fp,"\t%u",rrp->class);
- }
-
- if(rrp->type < NDTYPES)
- fprintf(fp,"\t%s",type2str(rrp->type));
- else
- fprintf(fp,"\t%u",rrp->type);
-
- if(rrp->rdlength != 0){
- fputc('\t',fp);
- switch(rrp->type){
- case TYPE_MINFO: /* Unsupported type */
- fprintf(fp,"%s\t%s",
- rrp->rdata.minfo.rmailbx,
- rrp->rdata.minfo.emailbx);
- break;
- case TYPE_MD: /* Unsupported type */
- case TYPE_MF: /* Unsupported type */
- case TYPE_NULL: /* Unsupported type */
- case TYPE_WKS: /* Unsupported type */
- fputs(rrp->rdata.data,fp);
- break;
- case TYPE_CNAME:
- case TYPE_MB:
- case TYPE_MG:
- case TYPE_MR:
- case TYPE_NS:
- case TYPE_PTR:
- case TYPE_TXT:
- /* These are all printable text strings */
- fputs(rrp->rdata.data,fp);
- break;
- case TYPE_A:
- fprintf(fp,"%s",inet_ntoa(rrp->rdata.addr));
- break;
- case TYPE_MX:
- fprintf(fp,"%u\t%s",rrp->rdata.mx.pref,
- rrp->rdata.mx.exch);
- break;
- case TYPE_SOA:
- fprintf(fp,"%s\t%s\t%lu\t%lu\t%lu\t%lu\t%lu",
- rrp->rdata.soa->mname,rrp->rdata.soa->rname,
- rrp->rdata.soa->serial,rrp->rdata.soa->refresh,
- rrp->rdata.soa->retry,rrp->rdata.soa->expire,
- rrp->rdata.soa->minimum);
- break;
- case TYPE_HINFO:
- fprintf(fp,"%s\t%s",
- rrp->rdata.hinfo.cpu,
- rrp->rdata.hinfo.os);
- break;
- default:
- break;
- }
- }
- fputc('\n',fp);
- fflush(fp);
- }
-
- /* Free a domain message */
- void
- free_dhdr(dp)
- struct dhdr *dp;
- {
- int i;
-
- if(dp->qdcount){
- for(i = 0; i < dp->qdcount; i++){
- xfree(dp->qlist[i]->qname);
- xfree((char *)dp->qlist[i]);
- }
- xfree((char *)dp->qlist);
- }
- if(dp->ancount){
- for(i = 0; i < dp->ancount; i++)
- free_rr(dp->ans[i]);
- xfree((char *)dp->ans);
- }
- if(dp->nscount){
- for(i = 0; i < dp->nscount; i++)
- free_rr(dp->ns[i]);
- xfree((char *)dp->ns);
- }
- if(dp->arcount){
- for(i = 0; i < dp->arcount; i++)
- free_rr(dp->add[i]);
- xfree((char *)dp->add);
- }
- xfree((char *)dp);
- }
-
- int
- ntohdomain(struct dhdr *dhdr,struct mbuf **bpp)
- {
- int i;
- int16 tmp, len = len_p(*bpp);
- char *cp,*msg;
-
- /* packet size must be greater then header size */
- if(len < 12)
- return -1;
-
- msg = mxallocw(len);
- pullup(bpp,msg,len);
- memset((char *)dhdr,0,sizeof(*dhdr));
-
-
- dhdr->id = get16(&msg[0]);
- tmp = get16(&msg[2]);
- if(tmp & DOM_RESPONSE)
- dhdr->qr = 1;
- dhdr->opcode = (tmp >> 11) & 0xf;
- if(tmp & DOM_AUTHORITY)
- dhdr->aa = 1;
- if(tmp & DOM_TRUNC)
- dhdr->tc = 1;
- if(tmp & DOM_DORECURSE)
- dhdr->rd = 1;
- if(tmp & DOM_CANRECURSE)
- dhdr->ra = 1;
- dhdr->rcode = tmp & 0xf;
- dhdr->qdcount = get16(&msg[4]);
- dhdr->ancount = get16(&msg[6]);
- dhdr->nscount = get16(&msg[8]);
- dhdr->arcount = get16(&msg[10]);
-
- /* Now parse the variable length sections */
- cp = &msg[12];
-
- /* Question section */
- if(dhdr->qdcount != 0)
- dhdr->qlist = (struct quest **)cxallocw(dhdr->qdcount,sizeof(struct quest *));
- for(i=0;i<dhdr->qdcount;i++){
- dhdr->qlist[i] = (struct quest *)mxallocw(sizeof(struct quest));
- if((cp = getq(dhdr->qlist[i],msg,cp)) == NULLCHAR)
- goto quit;
- }
- /* Answer section */
- if(dhdr->ancount != 0)
- dhdr->ans = (struct rr **)cxallocw(dhdr->ancount,sizeof(struct rr *));
- for(i=0;i<dhdr->ancount;i++){
- dhdr->ans[i] = (struct rr *)mxallocw(sizeof(struct rr));
- if((cp = ntohrr(dhdr->ans[i],msg,cp)) == NULLCHAR)
- goto quit;
- }
- /* Name server (authority) section */
- if(dhdr->nscount != 0)
- dhdr->ns = (struct rr **)cxallocw(dhdr->nscount,sizeof(struct rr *));
- for(i=0;i<dhdr->nscount;i++){
- dhdr->ns[i] = (struct rr *)mxallocw(sizeof(struct rr));
- if((cp = ntohrr(dhdr->ns[i],msg,cp)) == NULLCHAR)
- goto quit;
- }
- /* Additional section */
- if(dhdr->arcount != 0)
- dhdr->add = (struct rr **)cxallocw(dhdr->arcount,sizeof(struct rr *));
- for(i=0;i<dhdr->arcount;i++){
- dhdr->add[i] = (struct rr *)mxallocw(sizeof(struct rr));
- if((cp = ntohrr(dhdr->add[i],msg,cp)) == NULLCHAR)
- goto quit;
- }
- quit:
- xfree(msg);
- return 0;
- }
-
- void
- proc_answer(dhdr,dp,dfp)
- struct dhdr *dhdr;
- struct dserver *dp;
- FILE *dfp;
- {
- FILE *fp;
- int i;
- int32 rtt,abserr;
- long ttl = 500; /* Default TTL for negative records without SOA */
- struct rr *rrp;
- struct quest *qp;
-
- /* Compute and update the round trip time if its a domain server */
- if(dp != NULLDOM) {
- rtt = ((secclock() - (int32)dhdr->id)) * 1000;
- abserr = rtt > dp->srtt ? rtt - dp->srtt : dp->srtt - rtt;
- dp->srtt = ((AGAIN-1) * dp->srtt + rtt + (AGAIN/2)) >> LAGAIN;
- dp->mdev = ((DGAIN-1) * dp->mdev + abserr + (DGAIN/2)) >> LDGAIN;
- dp->timeout = 4 * dp->mdev + dp->srtt;
- }
-
- if(DBloaded == 1 && dfp == NULLFILE)
- fp = NULLFILE; /* append to memory */
- else {
- if(dfp == NULLFILE) {
- if((fp = open_file(Dfile,APPEND_TEXT,0,1)) == NULLFILE) {
- return;
- }
- } else {
- fp = dfp;
- }
- }
- if(dhdr->aa && (dhdr->rcode == NAME_ERROR || dhdr->ancount == 0)){
- /* Add negative reply to file. This assumes that there was
- * only one question, which is true for all questions we send.
- */
- qp = dhdr->qlist[0];
- rrp = (struct rr *)mxallocw(sizeof(struct rr));
- rrp->name = strxdup(qp->qname);
- rrp->type = qp->qtype;
- rrp->class = qp->qclass;
- rrp->ttl = ttl;
- rrp->rdlength = 0; /* no data */
- if(rrp->type == TYPE_A){
- if(add_rr(fp,rrp))
- free_rr(rrp); /* was already there */
- }
- }
- if(dhdr->rcode == NO_ERROR) {
- for(i=0;i< dhdr->ancount;i++){
- rrp = copy_rr(dhdr->ans[i]);
- if(rrp->type == TYPE_SOA)
- ttl = rrp->ttl;
- if(add_rr(fp,rrp))
- free_rr(rrp);
- }
- for(i=0;i< dhdr->nscount;i++){
- rrp = copy_rr(dhdr->ns[i]);
- if(rrp->type == TYPE_SOA)
- ttl = rrp->ttl;
- if(add_rr(fp,rrp))
- free_rr(rrp);
- }
- for(i=0;i< dhdr->arcount;i++){
- rrp = copy_rr(dhdr->add[i]);
- if(rrp->type == TYPE_SOA)
- ttl = rrp->ttl;
- if(add_rr(fp,rrp))
- free_rr(rrp);
- }
- }
- if(fp != NULLFILE && dfp == NULLFILE)
- fclose(fp);
- }
-
- char *
- type2str(type)
- int type;
- {
- char *Dtypes[] = {
- "", "A", "NS", "MD", "MF", "CNAME", "SOA", "MB", "MG",
- "MR", "NULL", "WKS", "PTR", "HINFO", "MINFO", "MX", "TXT"
- };
-
- if(type < NDTYPES)
- return Dtypes[type];
- else
- switch (type) {
- case TYPE_AXFR:
- return "AXFR";
- case TYPE_MAILB:
- return "MAILB";
- case TYPE_MAILA:
- return "MAILA";
- case TYPE_ANY:
- return "ANY";
- }
- return "UNKNOWN";
- }
-
- /* Return 1 if string appears to be an IP address in dotted decimal;
- * return 0 otherwise (i.e., if string is a domain name)
- */
- int
- isaddr(char *s)
- {
- char c;
-
- if(s != NULLCHAR) {
- while((c = *s++) != '\0'){
- if(c != '[' && c != '[' && !isdigit(c) && c != '.')
- return 0;
- }
- }
- return 1;
- }
-
- struct dhdr *
- bld_dhdr(qr,op,flags,rcode,name,class,type)
- int16 qr;
- int16 op;
- int16 flags;
- int16 rcode;
- char *name;
- int class;
- int type;
- {
- struct dhdr *dhdr = (struct dhdr *)mxallocw(sizeof(struct dhdr));
-
- dhdr->qr = qr;
- dhdr->opcode = op;
- if(flags & DOM_AUTHORITY)
- dhdr->aa = 1;
- if(flags & DOM_TRUNC)
- dhdr->tc = 1;
- if(flags & DOM_DORECURSE)
- dhdr->rd = 1;
- if(flags & DOM_CANRECURSE)
- dhdr->ra = 1;
- dhdr->rcode = rcode;
- dhdr->id = (int16)secclock();
- dhdr->qdcount = 1;
- dhdr->qlist = (struct quest **)cxallocw(dhdr->qdcount,sizeof(struct quest *));
- dhdr->qlist[0] = (struct quest *)mxallocw(sizeof(struct quest));
- dhdr->qlist[0]->qname = strxdup(name);
- dhdr->qlist[0]->qtype = type;
- dhdr->qlist[0]->qclass = class;
- return dhdr;
- }
-
- int
- res_mkbuf(dhdr,buffer,buflen)
- struct dhdr *dhdr;
- char *buffer; /* Area for query */
- int16 buflen; /* Length of same */
- {
- int16 parameter;
- int i, count;
- char *cp = buffer;
-
- cp = put16(cp,dhdr->id);
- parameter = (dhdr->qr) ? 0x8000 : 0;
- parameter |= ((dhdr->opcode & 0x0f) << 11);
- if(dhdr->aa)
- parameter |= DOM_AUTHORITY;
- if(dhdr->tc)
- parameter |= DOM_TRUNC;
- if(dhdr->rd)
- parameter |= DOM_DORECURSE;
- if(dhdr->ra)
- parameter |= DOM_CANRECURSE;
- parameter |= (dhdr->rcode & 0x0f);
- cp = put16(cp,parameter);
- cp = put16(cp,dhdr->qdcount);
- cp = put16(cp,dhdr->ancount);
- cp = put16(cp,dhdr->nscount);
- cp = put16(cp,dhdr->arcount);
- if((count = dhdr->qdcount) > 0) {
- for(i = 0; i < count; i++) {
- cp = dn_compress(cp,dhdr->qlist[i]->qname);
- cp = put16(cp,dhdr->qlist[i]->qtype);
- cp = put16(cp,dhdr->qlist[i]->qclass);
- }
- }
- if((count = dhdr->ancount) > 0)
- for(i = 0; i < count; i++) {
- cp = htonrr(dhdr->ans[i],cp);
- }
- if((count = dhdr->nscount) > 0)
- for(i = 0; i < count; i++) {
- cp = htonrr(dhdr->ns[i],cp);
- }
- if((count = dhdr->arcount) > 0)
- for(i = 0; i < count; i++) {
- cp = htonrr(dhdr->add[i],cp);
- }
- return (int)(cp - buffer);
- }
-
-